﻿using Shop.Core.Repository;
using Shop.Core.Share;
using Shop.IServices.Admin;
using Shop.Model.Dto.Admin.Goods;
using Shop.Model.Entity.Goo;
using Shop.Model.View.Admin.Goods;
using SqlSugar;

namespace Shop.Services.Admin;

public class GoodsService:AbstractService, IGoodsService
{
    private readonly RepositoryBase<GoodsGoods> _goodRepository;
    private readonly RepositoryBase<GoodsSize> _godSizeRepository;
    private readonly RepositoryBase<GoodsPrice> _godPriceRepository;
    private readonly RepositoryBase<GoodsUserLevel> _userLevelRepository;
    private readonly RepositoryBase<GoodsNewProduct> _newProductRepository;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="goodRepository"></param>
    /// <param name="godSizeRepository"></param>
    /// <param name="godPriceRepository"></param>
    /// <param name="userLevelRepository"></param>
    /// <param name="newProductRepository"></param>
    public GoodsService(RepositoryBase<GoodsGoods> goodRepository,
        RepositoryBase<GoodsSize> godSizeRepository,
        RepositoryBase<GoodsPrice> godPriceRepository,
        RepositoryBase<GoodsUserLevel> userLevelRepository,
        RepositoryBase<GoodsNewProduct> newProductRepository)
    {
        _goodRepository = goodRepository;
        _godSizeRepository = godSizeRepository;
        _godPriceRepository = godPriceRepository;
        _userLevelRepository = userLevelRepository;
        _newProductRepository = newProductRepository;
    }

    /// <summary>
    /// 商品列表
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<PageModel<GodListVo>> GodList(GodListDto dto)
    {
        var records = 0;
        var data = _goodRepository.Queryable<GoodsGoods, GoodsSize, GoodsPrice>((t1, t2, t3) => new object[]
            {
                JoinType.Left, t1.Id == t2.GoodsId && t2.IsDefault == true,
                JoinType.Left, t2.Id == t3.Size && t1.Id == t3.Goods
            })
            .WhereIF(!dto.State.HasValue || (dto.State.HasValue && dto.State.Value != 3), (t1, t2, t3) => t1.Valid == true)
            .WhereIF(!string.IsNullOrEmpty(dto.Code), (t1, t2, t3) => t2.Code == dto.Code)
            .WhereIF(!string.IsNullOrEmpty(dto.Name), (t1, t2, t3) => t1.Name.Contains(dto.Name))
            .WhereIF(dto.Type.HasValue, (t1, t2, t3) => t1.Type == dto.Type.Value)
            .WhereIF(dto.State.HasValue && dto.State.Value == 1, (t1, t2, t3) => t1.Saleable == true)
            .WhereIF(dto.State.HasValue && dto.State.Value == 2, (t1, t2, t3) => t1.Saleable == false)
            .WhereIF(dto.State.HasValue && dto.State.Value == 3, (t1, t2, t3) => t1.Valid == false)
            .WhereIF(dto.StartTime.HasValue, (t1, t2, t3) => t1.FoundTime >= dto.StartTime.Value)
            .WhereIF(dto.EndTime.HasValue, (t1, t2, t3) => t1.FoundTime < dto.EndTime.Value)
            .OrderBy("t1.FoundTime DESC")
            .Select((t1, t2, t3) => new GodListVo()
            {
                GId = t1.Id,
                Code = t2.Code,
                Img = t2.Thumbnail,
                GName = t1.Name,
                GSName = t2.Name,
                Price = t3.Price,
                Saleable = t1.Saleable,
                Type = t1.Type,
                FoundTime = t1.FoundTime
            })
            .ToPageList(dto.PageIndex, dto.PageSize, ref records);
        return new PageModel<GodListVo>(dto, data, records);
    }

    /// <summary>
    /// 新增商品
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult GodAdd(GodAddDto dto)
    {
        if (dto.Type == 2)
        {
            if (!dto.UserGrade.HasValue)
                return Problem("礼包，可购买商品用户等级不可为空");
            if (dto.IsNewProduct)
                return Problem("礼包不可添加为新品");
        }
        if (dto.IsNewProduct)
        {
            if (dto.NewProduct == null)
                return Problem("新品信息不可为空");
            if (!dto.NewProduct.Content.HasValue || dto.NewProduct.Content <= 0)
                return Problem("含量不可小于0");
            if (!dto.NewProduct.Spe.HasValue || dto.NewProduct.Spe <= 0)
                return Problem("容量不可小于0");
            if (string.IsNullOrEmpty(dto.NewProduct.Unit))
                return Problem("单位不可为空");
            if (string.IsNullOrEmpty(dto.NewProduct.Img))
                return Problem("图片不可为空");
            if (string.IsNullOrEmpty(dto.NewProduct.Title))
                return Problem("标题不可为空");
        }
        var goodsInfo = new GoodsGoods()
        {
            Name = dto.Name,
            Cover = dto.Cover,
            Banner = dto.Banner,
            Details = dto.Details,
            LineationPrice = dto.LineationPrice,
            Saleable = dto.Saleable,
            Spc = dto.Spc,
            Type = dto.Type
        };
        if (dto.UpTime.HasValue)
            goodsInfo.UpTime = dto.UpTime.Value;
        if (dto.DownTime.HasValue)
            goodsInfo.DownTime = dto.DownTime.Value;
        var goodId = _goodRepository.InsertReturnBigIdentity(goodsInfo);
        List<GoodsPrice> godPriceList = new List<GoodsPrice>();
        foreach (var item in dto.GodSizeList)
        {
            var godSizeInfo = new GoodsSize()
            {
                GoodsId = goodId,
                Code = item.Code,
                Thumbnail = item.Thumbnail,
                Stock = item.Stock,
                Valid = item.Valid,
                Name = item.Name,
                Count = item.Count,
                IsDefault = item.IsDefault,
                Point = item.Point
            };
            var sizeId = _godSizeRepository.InsertReturnBigIdentity(godSizeInfo);
            godPriceList.Add(new GoodsPrice()
            {
                Goods = goodId,
                Size = sizeId,
                Price = item.Price,
                OnePrice = item.OnePrice,
                TwoPrice = item.TwoPrice,
                ThreePrice = item.ThreePrice
            });
        }

        if (dto.Type == 2)
        {
            var useLevel = new GoodsUserLevel()
            {
                GoodsId = goodId,
                UserGrade = dto.UserGrade
            };
            _userLevelRepository.Insert(useLevel);
        }
        _godPriceRepository.InsertRange(godPriceList);

        if (dto.IsNewProduct)
        {
            var newProductInfo = _newProductRepository.Where(x => x.IsDelete == false).ToList();
            var newProduct = dto.NewProduct;
            var godNewProduct = new GoodsNewProduct()
            {
                Goods = goodId,
                Content = newProduct.Content.Value,
                Spe = newProduct.Spe.Value,
                Unit = newProduct.Unit,
                Img = newProduct.Img,
                Title = newProduct.Title
            };
            newProductInfo.ForEach(x => x.IsDelete = true);
            _newProductRepository.UpdateRange(newProductInfo);
            _newProductRepository.Insert(godNewProduct);
        }
        return new AppResult();
    }

    /// <summary>
    /// 商品详情
    /// </summary>
    /// <param name="gId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<GodDetailsVo> GodDetails(long gId)
    {
        var data = _goodRepository.Where(x => x.Id == gId)
            .Select(x => new GodDetailsVo()
            {
                GId = x.Id,
                Name = x.Name,
                Cover = x.Cover,
                Banner = x.Banner,
                Details = x.Details,
                LineationPrice = x.LineationPrice,
                Saleable = x.Saleable,
                Valid = x.Valid,
                Spc = x.Spc,
                UpTime = x.UpTime,
                DownTime = x.DownTime,
                Type = x.Type
            })
            .First();
        data.GodSizeList = _godSizeRepository.Queryable<GoodsSize, GoodsPrice>((t1, t2) => new object[]
            {
                JoinType.Left, t1.Id == t2.Size && t2.Goods == gId
            })
            .Where((t1, t2) => t1.GoodsId == gId)
            .Select((t1, t2) => new GoodsSizeList()
            {
                Code = t1.Code,
                Thumbnail = t1.Thumbnail,
                Stock = t1.Stock,
                Valid = t1.Valid,
                Name = t1.Name,
                Count = t1.Count,
                IsDefault = t1.IsDefault,
                Point = t1.Point,
                Price = t2.Price,
                OnePrice = t2.OnePrice,
                TwoPrice = t2.TwoPrice,
                ThreePrice = t2.ThreePrice
            })
            .ToList();
        return data;
    }

    /// <summary>
    /// 修改商品
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult GodEdit(GodEditDto dto)
    {
        var goodsInfo = _goodRepository.Where(x => x.Id == dto.Id).First();
        if (goodsInfo == null)
            return Problem("商品不存在");
        if (dto.Type == 2)
        {
            if (!dto.UserGrade.HasValue)
                return Problem("礼包，可购买商品用户等级不可为空");
        }
        try
        {
            _goodRepository.BeginTran();
            goodsInfo.Name = dto.Name;
            goodsInfo.Cover = dto.Cover;
            goodsInfo.Banner = dto.Banner;
            goodsInfo.Details = dto.Details;
            goodsInfo.LineationPrice = dto.LineationPrice;
            goodsInfo.Saleable = dto.Saleable;
            goodsInfo.Spc = dto.Spc;
            goodsInfo.Type = dto.Type;
            if (dto.UpTime.HasValue)
                goodsInfo.UpTime = dto.UpTime.Value;
            if (dto.DownTime.HasValue)
                goodsInfo.DownTime = dto.DownTime.Value;
            _goodRepository.Update(goodsInfo);
            _goodRepository.Change<GoodsPrice>().Delete(x => x.Goods == dto.Id);
            _goodRepository.Change<GoodsSize>().Delete(x => x.GoodsId == dto.Id);
            _goodRepository.Change<GoodsUserLevel>().Delete(x => x.GoodsId == dto.Id);
            List<GoodsPrice> godPriceList = new List<GoodsPrice>();
            foreach (var item in dto.GodSizeList)
            {
                var godSizeInfo = new GoodsSize()
                {
                    GoodsId = dto.Id,
                    Code = item.Code,
                    Thumbnail = item.Thumbnail,
                    Stock = item.Stock,
                    Valid = item.Valid,
                    Name = item.Name,
                    Count = item.Count,
                    IsDefault = item.IsDefault,
                    Point = item.Point
                };
                var sizeId = _goodRepository.Change<GoodsSize>().InsertReturnBigIdentity(godSizeInfo);
                godPriceList.Add(new GoodsPrice()
                {
                    Goods = dto.Id,
                    Size = sizeId,
                    Price = item.Price,
                    OnePrice = item.OnePrice,
                    TwoPrice = item.TwoPrice,
                    ThreePrice = item.ThreePrice
                });
            }
            if (dto.Type == 2)
            {
                var useLevel = new GoodsUserLevel()
                {
                    GoodsId = dto.Id,
                    UserGrade = dto.UserGrade
                };
                _goodRepository.Change<GoodsUserLevel>().Insert(useLevel);
            }
            _goodRepository.Change<GoodsPrice>().InsertRange(godPriceList);
            _goodRepository.CommitTran();
            return new AppResult();
        }
        catch (Exception e)
        {
            return Problem(e.Message);
        }
    }

    /// <summary>
    /// 删除商品
    /// </summary>
    /// <param name="gId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult GodDel(List<long> gId)
    {
        var data = _goodRepository.Where(x => gId.Contains(x.Id)).ToList();
        data.ForEach(x => x.Valid = false);
        _goodRepository.UpdateRange(data);
        return new AppResult();
    }

    /// <summary>
    /// 下架商品
    /// </summary>
    /// <param name="gId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult GodOut(List<long> gId)
    {
        var data = _goodRepository.Where(x => gId.Contains(x.Id)).ToList();
        data.ForEach(x => x.Saleable = false);
        _goodRepository.UpdateRange(data);
        return new AppResult();
    }
    
    /// <summary>
    /// 上架商品
    /// </summary>
    /// <param name="gId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult GodUp(List<long> gId)
    {
        var data = _goodRepository.Where(x => gId.Contains(x.Id)).ToList();
        data.ForEach(x => x.Saleable = true);
        _goodRepository.UpdateRange(data);
        return new AppResult();
    }
}